package com.cloud.punish.api.service.impl;

import com.cloud.punish.api.bean.*;
import com.cloud.punish.api.entity.*;
import com.cloud.punish.api.mapper.*;
import com.cloud.punish.api.service.RecPunishService;
import com.cloud.punish.common.consts.PunishConsts;
import com.cloud.punish.common.context.HumanSession;
import com.cloud.punish.common.result.SelectItem;
import com.cloud.punish.common.utils.SessionHelper;
import com.cloud.punish.common.utils.SqlConditionParserHelper;
import com.cloud.punish.interfaces.FeignClientLawCase;
import com.cloud.punish.interfaces.FeignClientMedia;
import com.cloud.punish.interfaces.FeignClientSystem;
import com.cloud.punish.workflow.command.create.CreateCommand;
import com.cloud.punish.workflow.command.create.CreateRequest;
import com.cloud.punish.workflow.command.create.CreateResponse;
import com.cloud.punish.workflow.service.WorkflowCoreService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class RecPunishServiceImpl implements RecPunishService {

	@Autowired
	private RecPunishMapper recPunishMapper;

	@Autowired
	private RecLitigantInfoMapper recLitigantInfoMapper;

	@Autowired
	private RecPunishInvestigationMapper recPunishInvestigationMapper;

	@Autowired
	private RecPunishEvidenceMapper recPunishEvidenceMapper;

	@Autowired
	private RecPunishInformMapper recPunishInformMapper;

	@Autowired
	private RecPunishHearingMapper recPunishHearingMapper;

	@Autowired
	private FeignClientSystem feignClientSystem;

	@Autowired
	private RecCauseMapper recCauseMapper;

	@Autowired
	private RecPunishDetailMapper recPunishDetailMapper;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private FeignClientMedia feignClientMedia;

	@Autowired
	private RecPunishRegisterMapper recPunishRegisterMapper;

	@Autowired
	private FeignClientLawCase feignClientLawCase;

	@Autowired
	private WorkflowCoreService workflowCoreService;

	@Override
	public RecPunishForm saveUpdate(RecPunishForm punish) {
		HumanSession session = SessionHelper.get();
		List<SelectItem> itemList = feignClientSystem.loadUnitDomainsByUnitId(session.getUnitId());
		punish.setIsPerfection(1);
		if (null == punish.getRecId() || 0 == punish.getRecId()) {
			HumanDetail detail = feignClientSystem.getHumanDetail(SessionHelper.get().getHumanId());
			// 保存案卷信息
			punish.setCreateHumanId(session.getHumanId());
			punish.setCreateHumanName(session.getHumanName());
			punish.setUnitId(session.getUnitId());
			punish.setUnitName(session.getUnitName());
			punish.setUnitCode(session.getUnitCode());
			Date date = new Date();
			punish.setCreateTime(date);
			punish.setUpdateTime(date);
			punish.setRegionCode(detail.getRegionCode());
			punish.setSubjectId(detail.getSubjectId());
			punish.setSubjectName(detail.getSubjectName());
			punish.setStateId(PunishConsts.REC_STATE_NORMAL);
			punish.setStateName(PunishConsts.REC_STATE_NAME_NORMAL);
			this.fillLitigantCauseInfo(punish);
			if (itemList.size() > 0) {
				List<String> idList = itemList.stream().filter(vo -> vo.getValue() != null)
						.map(vo -> vo.getValue().toString()).collect(Collectors.toList());
				List<String> nameList = itemList.stream().filter(vo -> StringUtils.isNotBlank(vo.getLabel()))
						.map(vo -> vo.getLabel()).collect(Collectors.toList());
				punish.setDomainTypeName(StringUtils.join(nameList, ","));
				punish.setDomainTypeId(StringUtils.join(idList, ","));
			}
			recPunishMapper.insert(punish);
			this.savePunishDetailInfo(punish);
			// 启动工作流
			if (null != punish.getProcDefId() && punish.getProcDefId() > 0) {
				workflowCoreService.execute(new CreateRequest(punish.getProcDefId(), punish.getRecId()), new CreateResponse(),
						new CreateCommand());
			}
		} else {
			// 当事人
			Example litigantExample = new Example(RecLitigantInfo.class);
			Example.Criteria litigantCriteria = litigantExample.createCriteria();
			litigantCriteria.andEqualTo("recId", punish.getRecId());
			recLitigantInfoMapper.deleteByExample(litigantExample);
			// 调查取证
			Example invExample = new Example(RecPunishInvestigation.class);
			Example.Criteria invCriteria = invExample.createCriteria();
			invCriteria.andEqualTo("recId", punish.getRecId());
			recPunishInvestigationMapper.deleteByExample(invExample);
			// 证据信息
			Example eviExample = new Example(RecPunishEvidence.class);
			Example.Criteria eviCriteria = eviExample.createCriteria();
			eviCriteria.andEqualTo("recId", punish.getRecId());
			recPunishEvidenceMapper.deleteByExample(eviExample);
			// 处罚告知
			Example informExample = new Example(RecPunishInform.class);
			Example.Criteria infromCriteria = informExample.createCriteria();
			infromCriteria.andEqualTo("recId", punish.getRecId());
			recPunishInformMapper.deleteByExample(informExample);
			// 听证
			Example hearExample = new Example(RecPunishHearing.class);
			Example.Criteria hearCriteria = hearExample.createCriteria();
			hearCriteria.andEqualTo("recId", punish.getRecId());
			recPunishHearingMapper.deleteByExample(hearExample);
			// 案由
			Example causeExample = new Example(RecCause.class);
			Example.Criteria causeCriteria = causeExample.createCriteria();
			causeCriteria.andEqualTo("recId", punish.getRecId());
			recCauseMapper.deleteByExample(causeExample);
			// 处罚裁量
			Example punishDetailExample = new Example(RecPunishDetail.class);
			Example.Criteria punishDetailCriteria = punishDetailExample.createCriteria();
			punishDetailCriteria.andEqualTo("recId", punish.getRecId());
			recPunishDetailMapper.deleteByExample(punishDetailExample);
			// 救济
			Example punishRegisterExample = new Example(RecPunishRegister.class);
			Example.Criteria punishRegisterCriteria = punishRegisterExample.createCriteria();
			punishRegisterCriteria.andEqualTo("recId", punish.getRecId());
			recPunishRegisterMapper.deleteByExample(punishDetailExample);
			// 设置unit_code 和 填报时间
			punish.setUnitCode(session.getUnitCode());
			punish.setCreateTime(recPunishMapper.selectByPrimaryKey(punish.getRecId()).getCreateTime());
			punish.setUpdateTime(new Date());
			if (itemList.size() > 0) {
				List<String> idList = itemList.stream().filter(vo -> vo.getValue() != null)
						.map(vo -> vo.getValue().toString()).collect(Collectors.toList());
				List<String> nameList = itemList.stream().filter(vo -> StringUtils.isNotBlank(vo.getLabel()))
						.map(vo -> vo.getLabel()).collect(Collectors.toList());
				punish.setDomainTypeId(StringUtils.join(idList, ","));
				punish.setDomainTypeName(StringUtils.join(nameList, ","));
			}
			// 更新案卷相关信息
			this.fillLitigantCauseInfo(punish);
			recPunishMapper.updateByPrimaryKey(punish);
			this.savePunishDetailInfo(punish);
		}
		return punish;
	}

	private void fillLitigantCauseInfo(RecPunishForm punish) {
		// 当事人名称
		if (punish.getLitigants().size() > 0) {
			List<String> litigantName = new ArrayList<String>();
			for (RecLitigantInfo litigant : punish.getLitigants()) {
				if (!StringUtils.isEmpty(litigant.getPersonName())) {
					litigantName.add(litigant.getPersonName());
				} else if (!StringUtils.isEmpty(litigant.getCompanyName())) {
					litigantName.add(litigant.getCompanyName());
				}
			}
			punish.setLitigantName(StringUtils.join(litigantName, ","));
		}
		// 案由
		if (punish.getCauses().size() > 0) {
			List<String> causes = new ArrayList<String>();
			for (RecCause cause : punish.getCauses()) {
				if (!StringUtils.isEmpty(cause.getCauseContent())) {
					causes.add(cause.getCauseContent());
				}
			}
			punish.setCauseContent(StringUtils.join(causes, ","));
		}
	}

	private void savePunishDetailInfo(RecPunishForm punish) {
		// 保存当事人信息
		List<RecLitigantInfo> infos = punish.getLitigants();
		if (null != infos && infos.size() > 0) {
			for (RecLitigantInfo info : infos) {
				info.setRecId(punish.getRecId());
				if ("01".equals(info.getLitigantTypeId())) {
					info.setCompanyAddress(null);
					info.setCompanyLegalPerson(null);
					info.setCompanyName(null);
					info.setCompanyPosition(null);
					info.setCompanySocialNum(null);
				} else {
					info.setPersonAddress(null);
					info.setPersonIdcardName(null);
					info.setPersonIdcardType(null);
					info.setPersonIdcardNum(null);
					info.setPersonName(null);
					info.setPersonAddress(null);
				}
				recLitigantInfoMapper.insert(info);
			}
		}
		// 保存调查取证信息
		if (null != punish.getInvestigations() && punish.getInvestigations().size() > 0) {
			for (RecPunishInvestigation inv : punish.getInvestigations()) {
				inv.setRecId(punish.getRecId());
				recPunishInvestigationMapper.insert(inv);
			}
		}
		// 保存证据信息
		if (null != punish.getEvidences() && punish.getEvidences().size() > 0) {
			for (RecPunishEvidence evi : punish.getEvidences()) {
				evi.setRecId(punish.getRecId());
				recPunishEvidenceMapper.insert(evi);
			}
		}
		// 保存处罚告知信息
		if (null != punish.getInforms() && punish.getInforms().size() > 0) {
			for (RecPunishInform inform : punish.getInforms()) {
				inform.setRecId(punish.getRecId());
				recPunishInformMapper.insert(inform);
			}
		}
		// 保存听证信息
		if (null != punish.getPunishHearings() && punish.getPunishHearings().size() > 0) {
			for (RecPunishHearing hear : punish.getPunishHearings()) {
				hear.setRecId(punish.getRecId());
				recPunishHearingMapper.insert(hear);
			}
		}
		// 保存案由相关信息
		if (null != punish.getCauses() && punish.getCauses().size() > 0) {
			for (RecCause cause : punish.getCauses()) {
				cause.setRecId(punish.getRecId());
				recCauseMapper.insert(cause);
				List<RecPunishDetail> details = cause.getPunishDetails();
				if (null != details && details.size() > 0) {
					for (RecPunishDetail detail : details) {
						detail.setCauseId(cause.getCauseId());
						detail.setRecId(punish.getRecId());
						recPunishDetailMapper.insert(detail);
					}
				}
			}
		}
		// 保存救济信息
		if (null != punish.getPunishRegisters() && punish.getPunishRegisters().size() > 0) {
			for (RecPunishRegister register : punish.getPunishRegisters()) {
				register.setRecId(punish.getRecId());
				recPunishRegisterMapper.insert(register);
			}
		}
	}

	@Override
	public RecPunishForm load(long recId) {
		RecPunishForm form = new RecPunishForm();
		RecPunish punish = recPunishMapper.selectByPrimaryKey(recId);
		BeanUtils.copyProperties(punish, form);
		String url = feignClientSystem.getSysConfigItem("DEFAULT_MEDIA_WEB_PATH_CONFIG");
		form.setPunishUrl(getUrl(form.getPunishDocId(), url));
		form.setPunishDocUrl(getUrl(form.getReceivedDocId(), url));
		form.setRegisterUrl(getUrl(form.getRegisterDocId(), url));
		// 当事人
		Example litigantExample = new Example(RecLitigantInfo.class);
		Example.Criteria litigantCriteria = litigantExample.createCriteria();
		litigantCriteria.andEqualTo("recId", punish.getRecId());
		List<RecLitigantInfo> litigants = recLitigantInfoMapper.selectByExample(litigantExample);
		form.setLitigants(litigants);
		// 调查取证
		Example invExample = new Example(RecPunishInvestigation.class);
		Example.Criteria invCriteria = invExample.createCriteria();
		invCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishInvestigation> investigations = recPunishInvestigationMapper.selectByExample(invExample);
		investigations.forEach(v -> {
			// 调查取证
			v.setInvestigationUrl(getUrl(v.getInvDocId(), url));
		});
		form.setInvestigations(investigations);
		// 证据信息
		Example eviExample = new Example(RecPunishEvidence.class);
		Example.Criteria eviCriteria = eviExample.createCriteria();
		eviCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishEvidence> evidences = recPunishEvidenceMapper.selectByExample(eviExample);
		evidences.forEach(v -> {
			// 证据信息
			v.setEvidenceUrl(getUrl(v.getEviDocId(), url));
		});
		form.setEvidences(evidences);
		// 处罚告知
		Example informExample = new Example(RecPunishInform.class);
		Example.Criteria infromCriteria = informExample.createCriteria();
		infromCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishInform> informs = recPunishInformMapper.selectByExample(informExample);
		informs.forEach(v -> {
			// 事先告知
			v.setInformDocUrl(getUrl(v.getInformDocId(), url));
			v.setReceiveDocUrl(getUrl(v.getReceivedDocId(), url));
		});
		form.setInforms(informs);
		// 听证
		Example hearExample = new Example(RecPunishHearing.class);
		Example.Criteria hearCriteria = hearExample.createCriteria();
		hearCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishHearing> hearings = recPunishHearingMapper.selectByExample(hearExample);
		form.setPunishHearings(hearings);
		// 案由处罚信息
		Example causeExample = new Example(RecCause.class);
		Example.Criteria causeCriteria = causeExample.createCriteria();
		causeCriteria.andEqualTo("recId", punish.getRecId());
		List<RecCause> causes = recCauseMapper.selectByExample(causeExample);
		// 案由裁量明细
		Example punishExample = new Example(RecCause.class);
		Example.Criteria punishCriteria = punishExample.createCriteria();
		punishCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishDetail> punishs = recPunishDetailMapper.selectByExample(punishExample);
		for (RecCause c : causes) {
			for (RecPunishDetail p : punishs) {
				if (c.getCauseId().longValue() == p.getCauseId().longValue()) {
					c.getPunishDetails().add(p);
				}
			}
		}
		List<String> causeCodes = new ArrayList<>();
		if (causes.size() > 0) {
			for (RecCause item : causes) {
				causeCodes.add(item.getCauseCode());
			}
		}
		List<LawCauseItem> casueIDs = feignClientLawCase.listCasueIDByCauseCode(causeCodes);
		for (LawCauseItem law : casueIDs) {
			for (RecCause c : causes) {
				if (law.getCauseCode().equals(c.getCauseCode())) {
					c.setId(law.getCauseId());
				}
			}
		}
		List<LawCauseRelCauseExcuteType> excuteTypes = feignClientLawCase.listExceuteTypeByCauseCode(causeCodes);
		if (excuteTypes != null && excuteTypes.size() > 0) {
			for (RecCause c : causes) {
				for (LawCauseRelCauseExcuteType p : excuteTypes) {
					RecPunishDetail detail = new RecPunishDetail();
					detail.setCauseId(p.getCauseId());
					detail.setExcuteTypeId(p.getExcuteTypeId().toString());
					detail.setExcuteTypeName(p.getExcuteTypeName());
					detail.setRecId(c.getRecId());
					c.getPunishTypes().add(detail);
				}
			}
		}
		List<LawCauseClDetail> clDetails = feignClientLawCase.listClDetailByCauseCode(causeCodes);
		if (clDetails != null && clDetails.size() > 0) {
			for (RecCause c : causes) {
				for (LawCauseClDetail clDetail : clDetails) {
					c.getClDetails().add(clDetail);
				}
			}
		}
		form.setCauses(causes);
		// 救济
		Example registerExample = new Example(RecPunishRegister.class);
		Example.Criteria registerCriteria = registerExample.createCriteria();
		registerCriteria.andEqualTo("recId", punish.getRecId());
		List<RecPunishRegister> punishRegisters = recPunishRegisterMapper.selectByExample(registerExample);
		form.setPunishRegisters(punishRegisters);
		return form;
	}

	private List<Map<String, Object>> getUrl(String ids, String url) {
		List<Map<String, Object>> informUrl = new ArrayList<>();
		if (StringUtils.isNotBlank(ids)) {
			String[] inform = ids.trim().split("/");
			List<Media> informList = feignClientMedia.getAllMediaByIds(Arrays.asList(inform));
			if (informList != null) {
				informList.forEach(j -> {
					Map<String, Object> map = new HashMap<>();
					map.put("name", j.getMediaName());
					map.put("url", url + j.getMediaPath());
					map.put("uid", j.getMediaId());
					informUrl.add(map);
				});
			}
		}
		return informUrl;
	}

	@Override
	public PageInfo<RecPunishSearchBean> searchPunishPage(RecPunishSearchCriteria criteria) {
		return PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize())
				.doSelectPageInfo(() -> recPunishMapper.searchPunishPage(criteria));
	}

	@Override
	public PageInfo<Map<String, Object>> statPunishPage(RecPunishStatCriteria criteria) {
		StringBuilder sqlBuilder = null;
		if (1 == criteria.getId()) {
			sqlBuilder = new StringBuilder(
					"select unit_name, sum(las) as las, sum(jycx) as jycx, sum(ybcx) as ybcx, sum(zcja) AS zcja, sum(cxla) as cxla, sum(bycf) as bycf, sum(cxcfjd) as cxcfjd, sum(zj) as zj, sum(punish_amount) as punish_amount from (")
							.append("select unit_id, unit_name, 1 as las, if(rec_type_id = '01', 1, 0) jycx, if(rec_type_id = '02', 1, 0) ybcx, if(finish_type_id = '01', 1, 0) zcja, if(finish_type_id = '02', 1, 0) cxla,if(finish_type_id = '03', 1, 0) bycf, if(finish_type_id = '04', 1, 0) cxcfjd, if(finish_type_id = '05', 1, 0) zj, punish_amount from rec_punish where state_id <> 99 ");
		} else {
			sqlBuilder = new StringBuilder(
					"select domain_type_name, sum(las) as las, sum(jycx) as jycx, sum(ybcx) as ybcx, sum(zcja) AS zcja, sum(cxla) as cxla, sum(bycf) as bycf, sum(cxcfjd) as cxcfjd, sum(zj) as zj, sum(punish_amount) as punish_amount from (")
							.append("select domain_type_id, domain_type_name, 1 as las, if(rec_type_id = '01', 1, 0) jycx, if(rec_type_id = '02', 1, 0) ybcx, if(finish_type_id = '01', 1, 0) zcja, if(finish_type_id = '02', 1, 0) cxla,if(finish_type_id = '03', 1, 0) bycf, if(finish_type_id = '04', 1, 0) cxcfjd, if(finish_type_id = '05', 1, 0) zj, punish_amount from rec_punish where state_id <> 99 ");
		}

		// 区划过滤，只能查看平级或下级区划的案卷信息
		if (!StringUtils.isEmpty(criteria.getRegionCode())) {
			sqlBuilder.append(" and region_code like '" + criteria.getRegionCode() + "%' ");
		}
		// 领域过滤只能查看管辖领域内的案卷
		if (null != criteria.getDomains() && criteria.getDomains().size() > 0) {
			sqlBuilder.append(" and domain_type_id in (" + StringUtils.join(criteria.getDomains(), ",") + ") ");
		}
		String conditions = SqlConditionParserHelper.buildConditionSql(criteria.getConds());
		if (!StringUtils.isEmpty(conditions)) {
			sqlBuilder.append(conditions);
		}
		if (1 == criteria.getId()) {
			sqlBuilder.append(" ) t group by unit_id");
		} else {
			sqlBuilder.append(" ) t group by domain_type_id");
		}
		final String sql = sqlBuilder.toString();
		return PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize())
				.doSelectPageInfo(() -> recPunishMapper.selectByDynamicSQL(sql));
	}

	@Override
	public void cancel(Long recId) {
		jdbcTemplate.update("update rec_punish set state_id = ?, state_name = ? where rec_id = ?",
				PunishConsts.REC_STATE_CANCEL, PunishConsts.REC_STATE_NAME_CANCEL, recId);
	}

	@Override
	public int caseTransfer(Long recId, HumanDetail humanDetail) {
		RecPunish recPunish = recPunishMapper.selectByPrimaryKey(recId);
		recPunish.setCreateHumanId(humanDetail.getHumanId());
		recPunish.setCreateHumanName(humanDetail.getHumanName());
		recPunish.setUnitId(humanDetail.getUnitId());
		recPunish.setUnitName(humanDetail.getUnitName());
		recPunish.setUnitCode(humanDetail.getUnitCode());
		recPunish.setSubjectId(humanDetail.getSubjectId());
		recPunish.setSubjectName(humanDetail.getSubjectName());
		recPunish.setRegionCode(humanDetail.getRegionCode());
		recPunish.setUpdateTime(new Date());
//		recPunish.setIsPerfection(1);
		return recPunishMapper.updateByPrimaryKey(recPunish);
	}

}
